package EA.operators.recombination;
import EA.*;
import RKUjava.math.*;

/** Uniform crossover on DiscreteRNumGenomes. This class implements four
    variants of the uniform crossover (see below).
*/
public class DRNumUniformCrossover extends NumCrossover
{

  public DRNumUniformCrossover()
    {
      super();
      crossovername = "uniform crossover";
    }


  /** Produce one offspring from two parents.
      @param parent1 The first parent.
      @param parent2 The second parent.
      @param params No parameters - pass null to the method.
  */
  public static NumericalGenome crossover(NumericalGenome parent1, NumericalGenome parent2, double[] params) 
    {
      int i;
      DiscreteRNumGenome offspring;
      DiscreteRNumGenome p1, p2;

      p1 = (DiscreteRNumGenome)parent1;
      p2 = (DiscreteRNumGenome)parent2;
	
      offspring = new DiscreteRNumGenome(parent1.framework,false);

      for (i=0; i<offspring.realpos.length; i++) {
	if (RKURandom.randomBoolean()) {
	  offspring.realpos[i] = p1.realpos[i];
	}
	else {
	  offspring.realpos[i] = p2.realpos[i];
	}
      }
      return offspring;
    }

  /** Produce one offspring from N parents.
      @param parents The parents.
      @param params No parameters - pass null to the method.
  */
  public static NumericalGenome crossover(NumericalGenome[] parents, double[] params) 
    {
      int i, j;
      DiscreteRNumGenome offspring;
	
      offspring = new DiscreteRNumGenome(parents[0].framework,false);

      for (i=0; i<offspring.realpos.length; i++) {
	offspring.realpos[i] = ((DiscreteRNumGenome)parents[RKURandom.randomInt(parents.length)]).realpos[i];
      }

      return offspring;
    }

  /** Produce an array offspring from two parents.
      @param parent1 The first parent.
      @param parent2 The second parent.
      @param params The parameters for the operator. 
      <ul>
      <li>First parameter: The number of offspring.
      </ul>
  */
  public static NumericalGenome[] crossover2(NumericalGenome parent1, NumericalGenome parent2, double[] params) 
    {
      DiscreteRNumGenome[] res;
      int i;
      res = new DiscreteRNumGenome[(int)params[0]];

      for (i=0; i<res.length; i++) {
	res[i] = (DiscreteRNumGenome)crossover(parent1, parent2, params);
      }
      return res;
    }


  /** Produce an array offspring from N parents.
      @param parents The parents.
      @param params The parameters for the operator. 
      <ul>
      <li>First parameter: The number of offspring.
      </ul>
  */
  public static NumericalGenome[] crossover2(NumericalGenome[] parents, double[] params) 
    {
      DiscreteRNumGenome[] res;
      int i;
      res = new DiscreteRNumGenome[(int)params[0]];

      for (i=0; i<res.length; i++) {
	res[i] = (DiscreteRNumGenome)crossover(parents, params);
      }
      return res;
    }

}
